<%@page import="java.util.HashMap"%>
<%@page import="com.mde.util.Validator"%>
<%@page import="com.mde.util.Point"%>
<%@page import="java.util.ArrayList"%>
<%@page import="java.util.List"%>
<%@page import="com.mde.util.Counter"%>
<%@page import="com.maptasksolver.struct.graph.Graph"%>
<%@page import="com.maptasksolver.struct.graph.Path"%>
<%@ page import="java.sql.*" %>
<%@ page 
		language="java" 
		contentType="text/html; charset=UTF-8"
    	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
    <title>Routes displaying page</title>
    <link rel="stylesheet" href="../styles.css">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="//api-maps.yandex.ru/2.0/?load=package.full&lang=ru-RU" type="text/javascript"></script>

	<script type="text/javascript" src="../js/displayingRoutesJs.js">
	</script>
</head>

<body>
	<div id="map" style="width:800px; height:600px"></div>	
<%!	
	Statement stmt;
	Connection con;
	String url = Validator.dbURL;	
	String ALL_EDGES_SELECT = "SELECT * FROM Edges WHERE fromId != 0;";
	int MAX_EDGES_COUNT = 400000;
	int MAX_VERTEXES_COUNT = 1000;
%>	
<%
	if (!Validator.validateStartAndFinish(request.getParameter("latitude1"),
			request.getParameter("latitude2"), request.getParameter("longitude1"), 
			request.getParameter("longitude2"))) {
		out.println("Wrong start and finish points data");
		return;
	}			

	List<Double> lats = new ArrayList<Double>();
	List<Double> lons = new ArrayList<Double>();
	List<Integer> pointIds = new ArrayList<Integer>();
	List<String> names = new ArrayList<String>();

	Class.forName("com.mysql.jdbc.Driver");
	con = DriverManager.getConnection(url, Validator.dbUsername, Validator.dbUserpass); 
	stmt = con.createStatement();

	// should be initialized properly without constants
	Graph g = new Graph(MAX_EDGES_COUNT, MAX_VERTEXES_COUNT);
	
	// Take all the edges and build graph
	ResultSet rs = stmt.executeQuery(ALL_EDGES_SELECT);
	
	int maxId = 0, fromId = 0, whereId = 0, maxRouteId = 0, routeId = 0; 	
	
	// Build the set of points connected with all the edges
	StringBuilder pointSet = new StringBuilder("(");
	
	fromId = rs.next() ? rs.getInt("fromId") : -1;
	if (fromId != -1) {
		whereId = rs.getInt("whereId");
		routeId = rs.getInt("routeId");
		g.addEdge(fromId, whereId, rs.getDouble("weight"), routeId);	
// 		System.out.println("From : " + fromId + ", Where : " + whereId + ", Weight : " + rs.getDouble("weight") + "<br/>");
		if (fromId > maxId) maxId = fromId;
		if (whereId > maxId) maxId = whereId;
		if (routeId > maxRouteId) maxRouteId = routeId;
	}
	pointSet.append(fromId + ", " + whereId);
	
// 	System.out.println("Path edges");
	while (rs.next()) {
		fromId = rs.getInt("fromId");
		whereId = rs.getInt("whereId");
		routeId = rs.getInt("routeId");
		
		pointSet.append(", " + fromId);
		pointSet.append(", " + whereId);
		
		g.addEdge(fromId, whereId, rs.getDouble("weight"), routeId);
// 		System.out.println("From : " + fromId + ", Where : " + whereId + ", Weight : " + rs.getDouble("weight") + "<br/>");
		
		if (fromId > maxId) maxId = fromId;
		if (whereId > maxId) maxId = whereId;
		if (routeId > maxRouteId) maxRouteId = routeId;
	}
	
	pointSet.append(")");
	
	// Initializing ids of starting and finishing points and id of edges from them
	fromId = maxId + 1;
	whereId = fromId + 1;
	++routeId;

// 	System.out.println("FromId = " + fromId + "<br/>");
// 	System.out.println("WhereId = " + whereId + "<br/>");
// 	System.out.println(pointSet.toString() + "<br/>");
	
	// Selecting all possible points to travel (they are connected by edges)
	rs = stmt.executeQuery("SELECT * FROM Points WHERE id IN " + pointSet + ";");
	
	// Now we'll add foot-path edges
	double fromLat = Double.parseDouble(request.getParameter("latitude1")), 
			fromLon = Double.parseDouble(request.getParameter("longitude1")),
			whereLat = Double.parseDouble(request.getParameter("latitude2")),
			whereLon = Double.parseDouble(request.getParameter("longitude2"));
	
	// Savinig start and finish points to the list
	lats.add(fromLat); lons.add(fromLon); pointIds.add(fromId); names.add("start");
	lats.add(whereLat); lons.add(whereLon); pointIds.add(whereId); names.add("finish");
	
// 	System.out.println("Foot edges");

	while (rs.next()) {
		double pointLat = rs.getDouble("latitude"),
				pointLon = rs.getDouble("longitude");
		
		lats.add(pointLat); lons.add(pointLon); pointIds.add(rs.getInt("id")); names.add(rs.getString("name"));
		
		// if it's a bus stop we can go there
		if (rs.getString("type").equals("bus_stop")) {
			int multy = Counter.WEIGHT_MULTIPLIER * Counter.FOOT_MULTIPLIER; 
			double weight = 
					multy *
					Counter.getDistance(fromLat, fromLon, pointLat, pointLon);
			g.addEdge(fromId, rs.getInt("id"), weight, routeId);
			
// 			System.out.println("From : " + fromId + ", Where : " + rs.getInt("id") + ", Weight : " + weight + "<br/>");
			
			weight = Counter.WEIGHT_MULTIPLIER * Counter.FOOT_MULTIPLIER *
					Counter.getDistance(pointLat, pointLon, whereLat, whereLon) * 10;
			g.addEdge(rs.getInt("id"), whereId, weight, routeId);
			
// 			System.out.println("From : " + rs.getInt("id") + ", Where : " + whereId + ", Weight : " + weight + "<br/>");
		}
	}	

	Path path = g.findPathDijkstra(fromId, whereId);
	// Getting string names of paths in route
	int vertexCount = path.getCount();
	int footPath = path.getPathNumber(vertexCount - 1);
	
	StringBuilder pathNumsSet = new StringBuilder("(");
	for (int i = 0; i < vertexCount - 1; ++i) {
		pathNumsSet.append(path.getPathNumber(i) + ", ");
	}
	pathNumsSet.append(path.getPathNumber(vertexCount - 1) + ")");
	
	rs = stmt.executeQuery("SELECT routeId, name FROM Routes WHERE routeId IN " + pathNumsSet + ";");
	HashMap<Integer, String> map = new HashMap<Integer, String>(); 
	
	while (rs.next()) 
		map.put(rs.getInt("routeId"), rs.getString("name"));

// 	System.out.println("Path<br/>");
// 	System.out.println("Path count = " + path.getCount());
%>

	<table class="hidden">
<%
	int count = 0;
	for (int i = path.getCount() - 1; i >= 0 ; --i) {
		int id = path.getVertex(i);
		int pathId = path.getPathNumber(i);
		Point point = Point.findPoint(pointIds, lats, lons, names, path.getVertex(i));
		double lat = point.getLat(), lon = point.getLon();
		String name = point.getName();
		//out.println(id + " " + lat + " " + lon + "<br/>");
%>
		<tr>
			<td id="<%= count%>path"><%= map.get(pathId) %></td>
			<td id="<%= count%>name"><%= name %></td>
			<td id="<%= count%>lat"><%= lat  %></td>
			<td id="<%= count++%>lon"><%= lon %></td>
		</tr>
<%
	}
	out.println("<tr><td id=\"count\">" + count + "</td></tr>");
%>
	</table>
<%
	stmt.close();
	con.close();
%>
    <div id="directions">
    </div>
</body>

</html>
